package com.devo.icecream.modbus

import com.devo.icecream.AppLogger
import com.devo.icecream.utils.ByteUtil
import com.serotonin.modbus4j.exception.ModbusTransportException
import com.serotonin.modbus4j.ip.tcp.TcpMaster
import com.serotonin.modbus4j.msg.WriteRegisterRequest
import com.serotonin.modbus4j.msg.WriteRegisterResponse
import com.serotonin.modbus4j.msg.WriteRegistersRequest
import com.serotonin.modbus4j.msg.WriteRegistersResponse

/**
 * 制作配方
 */
class Recipe {
    private val start = 10000
    private val skip = 2
    private val length = 20

    private val valueAddress by lazy {
        val arrays = IntArray(length)
        for (i in 0 until length) {
            arrays[i] = start + i * skip
        }
        arrays
    }
    private val weightAddress by lazy {
        val weightSkip = 1000
        val arrays = IntArray(length)
        for (i in 0 until length) {
            arrays[i] = start + weightSkip + i * skip
        }
        arrays
    }

    private val realWeightAddress by lazy {
        val weightSkip = 2000
        val arrays = IntArray(length)
        for (i in 0 until length) {
            arrays[i] = start + weightSkip + i * skip
        }
        arrays
    }

    //桶位ID
    private val list = mutableMapOf<Int, Float>()

    //将后台给的配方组合成配料集合
    fun addDosage(serial: Int, weight: Float) {
        if (list.size < valueAddress.size) {
            list[serial] = weight
        }
    }


    /**
     * 装填配方数据
     *
     * @param master
     * @throws ModbusTransportException
     */
    @Throws(ModbusTransportException::class)
    internal fun install(master: TcpMaster) {
        val countAddress = 8004
        val countResponse =
            master.send(WriteRegisterRequest(1, countAddress, list.size)) as WriteRegisterResponse

        AppLogger.w("写入数量:${countResponse.writeValue}")

        val values =
            list.map { ByteUtil.intToShortArray(it.key).toList() }.flatten()

        val valueResponse =
            master.send(
                WriteRegistersRequest(
                    1,
                    valueAddress[0],
                    values.toShortArray()
                )
            ) as WriteRegistersResponse

        AppLogger.w("写入配方:${ByteUtil.ByteArrToHex(ByteUtil.intToByteArray(valueResponse.numberOfRegisters))}")

        val weights = list.map { ByteUtil.floatToShortArray(it.value).toList() }.flatten()

        val weightResponse = master.send(
            WriteRegistersRequest(
                1,
                weightAddress[0],
                weights.toShortArray()
            )
        ) as WriteRegistersResponse

        AppLogger.w("写入重量:${ByteUtil.ByteArrToHex(ByteUtil.intToByteArray(weightResponse.numberOfRegisters))}")

    }

    override fun toString(): String {
        return "Recipe(start=$start, skip=$skip, length=$length, list=$list)"
    }


}